#include "catch.hpp"

#include "common/str.h"


TEST_CASE("str tests", "[str]") {
    using namespace std;
    using namespace evm::str;

    REQUIRE(lower("ABC") == "abc");
    REQUIRE(lower("A1b2C3d") == "a1b2c3d");

    REQUIRE(upper("abc") == "ABC");
    REQUIRE(upper("A1b2C3d") == "A1B2C3D");

    REQUIRE(startswith("abcdef", "abc"));
    REQUIRE(!startswith("abcdef", "abc", 3));
    REQUIRE(startswith("abcdef", "def", 3));
    REQUIRE(startswith("abcdef", "", 6));
    REQUIRE(startswith("abcdef", "", 6, 6));
    REQUIRE(!startswith("abcdef", "", 7));
    REQUIRE(!startswith("abcdef", "", 7, 7));
    REQUIRE(!startswith("abcdef", "def", 3, 5));

    REQUIRE(endswith("abcdef", "def"));
    REQUIRE(!endswith("abcdef", "def", 0, 4));
    REQUIRE(endswith("abcdef", "def", 2));
    REQUIRE(endswith("abcdef", "", 6));
    REQUIRE(endswith("abcdef", "", 6, 6));
    REQUIRE(!endswith("abcdef", "", 7));
    REQUIRE(!endswith("abcdef", "", 7, 7));
    REQUIRE(!endswith("abcdef", "def", 1, 5));

    REQUIRE(contains("abcdef", "cd"));
    REQUIRE(!contains("abcdef", "bdf"));

    REQUIRE(count("abc123abc123abc", "abc") == 3);
    REQUIRE(count("abc123abc123abc", "abcabc") == 0);

    REQUIRE(iequals("A1b2C3d", "a1B2c3D"));

    REQUIRE(join(",", {"ab", "cd", "ef"}) == "ab,cd,ef");
    REQUIRE(join(",", {}) == "");

    vector<string> split_strings{"ab", "cd", "ef"};
    REQUIRE(split("ab cd ef") == split_strings);
    REQUIRE(split("ab cd ef", " ") == split_strings);
    REQUIRE(split("  ab  cd      ef    ") == split_strings);
    split_strings = {"", "", "ab", "", "", "cd", "", "ef", ""};
    REQUIRE(split("  ab   cd  ef ", " ") == split_strings);
    split_strings = {"ab", "cd ef"};
    REQUIRE(split("ab cd ef", 1) == split_strings);
    REQUIRE(split("  ab cd ef", 1) == split_strings);
    split_strings = {"", "", "ab   cd  ef "};
    REQUIRE(split("  ab   cd  ef ", " ", 2) == split_strings);
    split_strings = {"ab"};
    REQUIRE(split("  ab ") == split_strings);
    split_strings = {};
    REQUIRE(split("  ") == split_strings);
    REQUIRE(split("  ", 1) == split_strings);

    REQUIRE(slice("abcdefg", 1, 5) == "bcde");
    REQUIRE(slice("abcdefg", 1, 5, 2) == "bd");
    REQUIRE(slice("abcdefg", 1, 4, 2) == "bd");
    REQUIRE(slice("abcdefg", 1, 6, 2) == "bdf");
    REQUIRE(slice("abcdefg", -5, -1) == "cdef");
    REQUIRE(slice("abcdefg", -1, -5, -1) == "gfed");
    REQUIRE(slice("abcdefg", -1, -5, -2) == "ge");

    REQUIRE(replace("abcdefg", "cde", "CDE") == "abCDEfg");
    REQUIRE(replace("abcdefgabcdefg", "cde", "CDE") == "abCDEfgabCDEfg");
    REQUIRE(replace("abcdefgabcdefg", "cde", "CDE", 1) == "abCDEfgabcdefg");

    REQUIRE(strip(" \t \nabc  \r \v") == "abc");
    REQUIRE(lstrip(" \t \nabc  \r \v") == "abc  \r \v");
    REQUIRE(rstrip(" \t \nabc  \r \v") == " \t \nabc");
    REQUIRE(strip(" \t \n \f  \r \v") == "");
    REQUIRE(lstrip(" \t \n \f  \r \v") == "");
    REQUIRE(rstrip(" \t \n \f  \r \v") == "");
    REQUIRE(strip("abc") == "abc");
    REQUIRE(lstrip("abc") == "abc");
    REQUIRE(rstrip("abc") == "abc");
}
